
#include "utils.h"
#include "view.h"

#include <stdio.h>
#include <string.h>

static void bb_clear_output_props(struct bb_output_props* props)
{
    props->type = BB_OUTPUT_UNKNOWN;
    props->error_substr = NULL;
    props->warning_substr = NULL;
}

void bb_view_init(
        struct bb_view* view, 
        bb_view_output_listener listener,
        void* listener_arg0)
{
    view->listener = listener;
    view->listener_arg0 = listener_arg0;
}

void bb_view_uninit(struct bb_view* view)
{
    (void)view;
}

void bb_view_on_build_output(struct bb_view* view, char const* line)
{
    struct bb_output_props props;
    bb_clear_output_props(&props);

    if ( (props.error_substr = strstr(line, "error:")) )
        props.type = BB_OUTPUT_BUILD_ERROR;
    else if ( (props.warning_substr = strstr(line, "warning:")) )
        props.type = BB_OUTPUT_BUILD_WARNING;
    else
        props.type = BB_OUTPUT_BUILD_OTHER;
    (*view->listener)(view->listener_arg0, &props, line);
}

void bb_view_on_control_output(struct bb_view* view, char const* line)
{
    struct bb_output_props props;
    bb_clear_output_props(&props);
    props.type = BB_OUTPUT_CONTROL;
    (*view->listener)(view->listener_arg0, &props, line);
}

void bb_view_stdout_output_listener(void* unused, struct bb_output_props const* props, char const* line)
{
    (void)unused;

    switch (props->type)
    {
    case BB_OUTPUT_BUILD_ERROR: {
        int const prefix_len = (int)(props->error_substr - line);
        fprintf(stdout, "%.*s\t\033[1;31m%s\033[1;37m\n", prefix_len, line, props->error_substr);
        break;
    }
    case BB_OUTPUT_BUILD_WARNING: {
        int const prefix_len = (int)(props->warning_substr - line);
        fprintf(stdout, "%.*s\t\033[1;34m%s\033[1;37m\n", prefix_len, line, props->warning_substr);
        break;
    }
    case BB_OUTPUT_BUILD_OTHER:
        fprintf(stdout, "%s\n", line);
        break;
    case BB_OUTPUT_CONTROL: {
        struct timeval now;
        gettimeofday(&now, NULL);
        char buffer[64];
        bb_format_time(&now, buffer);
        fprintf(stdout, "\033[1;32m---> [%s] %s\033[1;37m\n", buffer, line);
        break;
    }
    default:
        break;
    }
}

